#include <time.h>
#include "../core/time/SpTime.h"

///////////////////////////////////////////////////////////////////////
//  CKData
_BOND_INLINE int CKData::GetUpperBound() const
{ return m_nSize-1; }
_BOND_INLINE void CKData::RemoveAll()
{ SetSize(0); }
_BOND_INLINE KDATA CKData::GetAt(int nIndex) const
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE void CKData::SetAt(int nIndex, const KDATA & newElement)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
m_pData[nIndex] = newElement; }
_BOND_INLINE KDATA& CKData::ElementAt(int nIndex)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE const KDATA* CKData::GetData() const
{ return (const KDATA*)m_pData; }
_BOND_INLINE KDATA* CKData::GetData()
{ return (KDATA*)m_pData; }
_BOND_INLINE KDATA CKData::operator[](int nIndex) const
{ return GetAt(nIndex); }
_BOND_INLINE KDATA& CKData::operator[](int nIndex)
{ return ElementAt(nIndex); }
_BOND_INLINE bool CKData::DateAt(int nIndex,
								 int &nYear, int &nMonth, int &nDay, int &nHour, int &nMinute ) const
{
	Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
	if( nIndex < 0 || nIndex >= m_nSize )
		return 0;
	DWORD	date	=	m_pData[nIndex].m_date;
	CSPTime	sptime;
	bool	bOK	=	false;
	if( ktypeMonth == m_nKType 
		|| ktypeWeek == m_nKType 
		|| ktypeDay == m_nKType )
	{
		bOK	=	sptime.FromStockTimeDay( date );
	}
	else if( ktypeMin60 == m_nKType
		|| ktypeMin30 == m_nKType
		|| ktypeMin15 == m_nKType
		|| ktypeMin5 == m_nKType )
	{
		bOK	=	sptime.FromStockTimeMin( date );
	}
	else
	{
		nYear	=	nMonth	=	nDay	=	nHour	=	nMinute	=	0;
		return false;
	}
	if( !bOK )
		return false;

	nYear	=	sptime.GetYear();
	nMonth	=	sptime.GetMonth();
	nDay	=	sptime.GetDay();
	nHour	=	sptime.GetHour();
	nMinute	=	sptime.GetMinute();

	return true;
}
_BOND_INLINE float	CKData::MaindataAt(int nIndex)
// 得到CKData的nIndex日的主数据，根据主数据类型不同，返回值可能是开盘价、收盘价或者平均价
{
	Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
	if( nIndex < 0 || nIndex >= m_nSize )
		return 0;
	if (mdtypeOpen == m_nCurMaindataType)
		return GetFRightOpen(nIndex);// m_pData[nIndex].m_fOpen;
	else if( mdtypeAverage == m_nCurMaindataType
		&& m_pData[nIndex].m_fVolume > 1e-4 && m_pData[nIndex].m_fAmount > 1e-4 )
	{
		int		nCount	=	0;
		double	average	=	((double)(m_pData[nIndex].m_fAmount)) / m_pData[nIndex].m_fVolume;
		if (strstr(m_pData[nIndex].m_szCode, SS_TWO_TF_FLAG)) average /= 2.0;
		while (average < GetFRightLow(nIndex) && nCount < 10)	{ average *= 10;	nCount++; }
		while (average > GetFRightHign(nIndex) && nCount < 20)	{ average /= 10;	nCount++; }
		if (average < GetFRightLow(nIndex))		//	说明是指数
			average = (GetFRightOpen(nIndex) + GetFRightHign(nIndex) + GetFRightLow(nIndex) + GetFRightClose(nIndex)) / 4;
		return (float)average;
	}
	else
		return GetFRightClose(nIndex);

	// WARNING CPV::Calculate( ... ) use the save code.
}

///////////////////////////////////////////////////////////////////////
//  CBaseData
_BOND_INLINE int CBaseData::GetSize() const
{ return m_nSize; }
_BOND_INLINE int CBaseData::GetUpperBound() const
{ return m_nSize-1; }
_BOND_INLINE void CBaseData::RemoveAll()
{ SetSize(0); }
_BOND_INLINE BASEDATA CBaseData::GetAt(int nIndex) const
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE void CBaseData::SetAt(int nIndex, const BASEDATA &newElement)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
m_pData[nIndex] = newElement; }
_BOND_INLINE BASEDATA& CBaseData::ElementAt(int nIndex)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE const BASEDATA* CBaseData::GetData() const
{ return (const BASEDATA*)m_pData; }
_BOND_INLINE BASEDATA* CBaseData::GetData()
{ return (BASEDATA*)m_pData; }
_BOND_INLINE int CBaseData::Add(const BASEDATA & newElement)
{ int nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
return nIndex; }
_BOND_INLINE BASEDATA CBaseData::operator[](int nIndex) const
{ return GetAt(nIndex); }
_BOND_INLINE BASEDATA& CBaseData::operator[](int nIndex)
{ return ElementAt(nIndex); }

///////////////////////////////////////////////////////////////////////
//  CBondReport
_BOND_INLINE int CBondReport::GetSize() const
{ return m_nSize; }
_BOND_INLINE int CBondReport::GetUpperBound() const
{ return m_nSize-1; }
_BOND_INLINE void CBondReport::RemoveAll()
{ SetSize(0); }
_BOND_INLINE REPORTF CBondReport::GetAt(int nIndex) const
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE void CBondReport::SetAt(int nIndex, const REPORTF & newElement)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
m_pData[nIndex] = newElement; }
_BOND_INLINE REPORTF& CBondReport::ElementAt(int nIndex)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE const REPORTF* CBondReport::GetData() const
{ return (const REPORTF*)m_pData; }
_BOND_INLINE REPORTF* CBondReport::GetData()
{ return (REPORTF*)m_pData; }
_BOND_INLINE int CBondReport::Add(const REPORTF & newElement)
{ int nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
return nIndex; }
_BOND_INLINE REPORTF CBondReport::operator[](int nIndex) const
{ return GetAt(nIndex); }
_BOND_INLINE REPORTF& CBondReport::operator[](int nIndex)
{ return ElementAt(nIndex); }

///////////////////////////////////////////////////////////////////////
//  CBondQuote
_BOND_INLINE int CBondQuote::GetSize() const
{ return m_nSize; }
_BOND_INLINE int CBondQuote::GetUpperBound() const
{ return m_nSize-1; }
_BOND_INLINE void CBondQuote::RemoveAll()
{ SetSize(0); }
_BOND_INLINE QUOTE CBondQuote::GetAt(int nIndex) const
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE void CBondQuote::SetAt(int nIndex, const QUOTE & newElement)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
m_pData[nIndex] = newElement; }
_BOND_INLINE QUOTE& CBondQuote::ElementAt(int nIndex)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE const QUOTE* CBondQuote::GetData() const
{ return (const QUOTE*)m_pData; }
_BOND_INLINE QUOTE* CBondQuote::GetData()
{ return (QUOTE*)m_pData; }
_BOND_INLINE int CBondQuote::Add(const QUOTE & newElement)
{ int nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
return nIndex; }
_BOND_INLINE QUOTE CBondQuote::operator[](int nIndex) const
{ return GetAt(nIndex); }
_BOND_INLINE QUOTE& CBondQuote::operator[](int nIndex)
{ return ElementAt(nIndex); }

///////////////////////////////////////////////////////////////////////
//  CBondMinute
_BOND_INLINE int CBondMinute::GetSize() const
{ return m_nSize; }
_BOND_INLINE int CBondMinute::GetUpperBound() const
{ return m_nSize-1; }
_BOND_INLINE void CBondMinute::RemoveAll()
{ SetSize(0); }
_BOND_INLINE MINUTE CBondMinute::GetAt(int nIndex) const
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE void CBondMinute::SetAt(int nIndex, const MINUTE & newElement)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
m_pData[nIndex] = newElement; }
_BOND_INLINE MINUTE& CBondMinute::ElementAt(int nIndex)
{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
return m_pData[nIndex]; }
_BOND_INLINE const MINUTE* CBondMinute::GetData() const
{ return (const MINUTE*)m_pData; }
_BOND_INLINE MINUTE* CBondMinute::GetData()
{ return (MINUTE*)m_pData; }
_BOND_INLINE int CBondMinute::Add(const MINUTE & newElement)
{ int nIndex = m_nSize;
SetAtGrow(nIndex, newElement);
return nIndex; }
_BOND_INLINE MINUTE CBondMinute::operator[](int nIndex) const
{ return GetAt(nIndex); }
_BOND_INLINE MINUTE& CBondMinute::operator[](int nIndex)
{ return ElementAt(nIndex); }

///////////////////////////////////////////////////////////////////////
//  CBondCash
_BOND_INLINE int CBondCash::GetSize() const
	{ return m_nSize; }
_BOND_INLINE int CBondCash::GetUpperBound() const
	{ return m_nSize-1; }
_BOND_INLINE void CBondCash::RemoveAll()
	{ SetSize(0); }
_BOND_INLINE CASH CBondCash::GetAt(int nIndex) const
	{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
		return m_pData[nIndex]; }
_BOND_INLINE void CBondCash::SetAt(int nIndex, const CASH & newElement)
	{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
		m_pData[nIndex] = newElement; }
_BOND_INLINE CASH& CBondCash::ElementAt(int nIndex)
	{ Q_ASSERT(nIndex >= 0 && nIndex < m_nSize);
		return m_pData[nIndex]; }
_BOND_INLINE const CASH* CBondCash::GetData() const
	{ return (const CASH*)m_pData; }
_BOND_INLINE CASH* CBondCash::GetData()
	{ return (CASH*)m_pData; }
_BOND_INLINE int CBondCash::Add(const CASH & newElement)
	{ int nIndex = m_nSize;
		SetAtGrow(nIndex, newElement);
		return nIndex; }
_BOND_INLINE CASH CBondCash::operator[](int nIndex) const
	{ return GetAt(nIndex); }
_BOND_INLINE CASH& CBondCash::operator[](int nIndex)
	{ return ElementAt(nIndex); }
